<template>
  <div style="border: 1px solid #ccc">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      style="height: 500px; overflow-y: hidden;"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChangeHtml"
    />
  </div>
</template>

<script setup>
import { getToken } from "@/utils/auth"
import "@wangeditor/editor/dist/css/style.css"
import { Editor, Toolbar } from "@wangeditor/editor-for-vue"
const emit = defineEmits()
const props = defineProps({
  modelValue: { type: String }
})
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()

// 内容 HTML
const mode = ref("default")
const valueHtml = ref("")
watch(
  () => props.modelValue,
  v => {
    if (v !== valueHtml.value) {
      valueHtml.value = v === undefined ? "<p></p>" : v
    }
  },
  { immediate: true }
)

const toolbarConfig = {
  /* 显示哪些菜单，如何排序、分组 */
  toolbarKeys: [
    "bold",
    "underline",
    "italic",
    {
      key: "group-more-style",
      title: "",
      iconSvg:
        '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
      menuKeys: ["through", "code", "sub", "sup", "clearStyle"]
    },
    "color",
    "bgColor",
    "|",
    "fontSize",
    "fontFamily",
    "lineHeight",
    "|",
    "bulletedList",
    "numberedList",
    "todo",
    {
      key: "group-justify",
      title: "对齐",
      iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
      menuKeys: ["justifyLeft", "justifyRight", "justifyCenter", "justifyJustify"]
    },
    {
      key: "group-indent",
      title: "缩进",
      iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
      menuKeys: ["indent", "delIndent"]
    },
    "|",
    "headerSelect",
    "blockquote",
    "insertLink",
    {
      key: "group-image",
      title: "图片",
      iconSvg:
        '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',
      menuKeys: ["insertImage", "uploadImage"]
    },
    "uploadVideo",
    "insertTable",
    "codeBlock",
    "divider",
    "|",
    "redo",
    "undo",
    "|",
    "fullScreen"
  ]
  /* 隐藏哪些菜单 */
  // excludeKeys: [],
}
const editorConfig = {
  placeholder: "请输入内容...",
  readOnly: false,
  // autoFocus: false,
  // 所有的菜单配置，都要在 MENU_CONF 属性下
  MENU_CONF: {
    uploadImage: {
      // 必填
      server: import.meta.env.VITE_APP_BASE_API + "/common/uploadOss",
      // 自定义增加 http  header
      headers: {
        Authorization: "Bearer " + getToken()
      },
      // form-data fieldName ，默认值 'wangeditor-uploaded-image'
      fieldName: "file",
      // 单个文件的最大体积限制，默认为 2M
      maxFileSize: 20 * 1024 * 1024, // M
      // 最多可上传几个文件，默认为 100
      maxNumberOfFiles: 10,
      // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
      allowedFileTypes: [],
      // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
      meta: {},
      // 将 meta 拼接到 url 参数中，默认 false
      metaWithUrl: false,
      // 跨域是否传递 cookie ，默认为 false
      withCredentials: true,
      // 超时时间，默认为 10 秒
      timeout: 20 * 1000,
      // 小于该值就插入 base64 格式（而不上传），默认为 0
      // 5kb
      base64LimitSize: 5 * 1024,
      // 上传之前触发
      onBeforeUpload(file) {
        // file 选中的文件，格式如 { key: file }
        return file
        // 可以 return
        // 1. return file 或者 new 一个 file ，接下来将上传
        // 2. return false ，不上传这个 file
      },

      // 上传进度的回调函数
      onProgress(progress) {
        // progress 是 0-100 的数字
        console.log("progress", progress)
      },
      // 单个文件上传成功之后
      onSuccess(file, res) {
        console.log(`${file.name} 上传成功`, res)
      },
      // 单个文件上传失败
      onFailed(file, res) {
        console.log(`${file.name} 上传失败`, res)
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        console.log(`${file.name} 上传出错`, err, res)
      },
      // 使用 customInsert 来自定义插入图片
      customInsert(res, insertFn) {
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ，然后插入图片
        insertFn(res.url, res.originalFilename, res.url)
      }
    },
    uploadVideo: {
      // 必填
      server: import.meta.env.VITE_APP_BASE_API + "/common/uploadOss",
      // 自定义增加 http  header
      headers: {
        Authorization: "Bearer " + getToken()
      },
      // form-data fieldName ，默认值 'wangeditor-uploaded-image'
      fieldName: "file",
      // 单个文件的最大体积限制，默认为 2M
      maxFileSize: 20 * 1024 * 1024, // 1M
      // 最多可上传几个文件，默认为 100
      maxNumberOfFiles: 10,
      // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
      allowedFileTypes: [],
      // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
      meta: {},
      // 将 meta 拼接到 url 参数中，默认 false
      metaWithUrl: false,
      // 跨域是否传递 cookie ，默认为 false
      withCredentials: true,
      // 超时时间，默认为 10 秒
      timeout: 20 * 1000,
      // 上传之前触发
      onBeforeUpload(file) {
        // file 选中的文件，格式如 { key: file }
        return file
        // 可以 return
        // 1. return file 或者 new 一个 file ，接下来将上传
        // 2. return false ，不上传这个 file
      },

      // 上传进度的回调函数
      onProgress(progress) {
        // progress 是 0-100 的数字
        console.log("progress", progress)
      },
      // 单个文件上传成功之后
      onSuccess(file, res) {
        console.log(`${file.name} 上传成功`, res)
      },
      // 单个文件上传失败
      onFailed(file, res) {
        console.log(`${file.name} 上传失败`, res)
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        console.log(`${file.name} 上传出错`, err, res)
      },
      // 使用 customInsert 来自定义插入图片
      customInsert(res, insertFn) {
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ，然后插入图片
        insertFn(res.url, res.originalFilename, res.url)
      }
    }
  }
}

function handleChangeHtml(editor) {
  emit("update:modelValue", editor.getHtml())
}
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

const handleCreated = editor => {
  editorRef.value = editor // 记录 editor 实例，重要！
}
</script>    

<style>
</style>